package com.bluezone.dec.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bluezone.dec.common.CacheConstant;
import com.bluezone.dec.common.SystemConstant;
import com.bluezone.dec.configuration.AppConfig;
import com.bluezone.dec.system.service.EnterpriseService;
import com.bluezone.dec.system.service.ParkEnvironmentProtectStatisticsService;
import com.bluezone.dec.system.vo.ComplaintWayVo;
import com.bluezone.dec.system.vo.EnvironmentBaseVo;
import com.bluezone.dec.system.vo.PenaltyVo;
import com.bluezone.dec.utils.TimeTransferUtils;
import com.google.common.base.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author HHL
 * @description 园区环保情况统计服务层接口实现类
 * @date 2018/11/12 - 11:40
 */
@Service
public class ParkEnvironmentProtectStatisticsServiceImpl implements ParkEnvironmentProtectStatisticsService {

  @Autowired
  private AppConfig appConfig;
  @Autowired
  private EnterpriseService enterpriseService;
  @Autowired
  private RedisTemplate redisTemplate;

  /**
   * 行政处罚处罚情况-过滤“时间”字段在当年的，
   * 按“时间”字段做月份分组，
   * 按“处罚类型”做系列分组，对记录数做分组计数
   *
   * @return
   */
  @Override
  public Map<String, Object> getAdministrativePenalStatus() {

    if (!redisTemplate.hasKey(CacheConstant.ADMINISTRATIVE_PENALTY)) {

      /* 获取当月往前一年的时间列表 */
      List<String> dayList = TimeTransferUtils.getDayList();

      List<PenaltyVo> penaltyVoList = this.getCurrentPenaltyInfo();

      /* 按处罚类型和处罚时间分组 */
      Map<String, Map<String, Long>> result = penaltyVoList
          .stream()
          .collect(Collectors.groupingBy(PenaltyVo::getAdministrativePenaltyType,
              Collectors.groupingBy(PenaltyVo::getDate,
                  Collectors.counting())));

      /* 定义结果集列表 */
      List<Map<String, Object>> resultList = new ArrayList<>();

      /* 遍历分组统计结果集 */
      result.forEach((penaltyType, dateAndCountMap) -> {

        Map<String, Object> penalTypeAndCountMap = new HashMap<>();
        penalTypeAndCountMap.put(SystemConstant.NAME, penaltyType);
        List<Long> perMonthCountList = new ArrayList<>();

        /* 将dateAndCountMap的key遍历取出转为集合 */
        List<String> keys = dateAndCountMap.entrySet().stream().map(m -> m.getKey()).collect(Collectors.toList());

        /* 遍历当前月往前一年时间，设置每个月份每种投诉方式对应的记录数 */
        dayList.forEach(m -> {
          if (keys.contains(m)) {
            perMonthCountList.add(dateAndCountMap.get(m));
          } else {
            perMonthCountList.add(0L);
          }
        });

        penalTypeAndCountMap.put(SystemConstant.VALUE, perMonthCountList);
        resultList.add(penalTypeAndCountMap);
      });

      Map<String, Object> resultMap = new HashMap<>();
      resultMap.put("dateList", dayList);
      resultMap.put(SystemConstant.VALUE, resultList);

      /* 设置行政处罚处罚情况缓存过期时间 */
      redisTemplate.opsForValue().set(CacheConstant.ADMINISTRATIVE_PENALTY,
          JSON.toJSONString(resultMap),
          appConfig.getChartDataCacheTime(),
          TimeUnit.SECONDS);

      return resultMap;
    } else {
      Object penaltyMapString = redisTemplate.opsForValue().get(CacheConstant.ADMINISTRATIVE_PENALTY);
      /* json 转 map */
      return JSON.parseObject(penaltyMapString.toString(), Map.class);
    }
  }


  /**
   * 行政处罚处罚情况-获取往前一年的所有行政处罚及其对应月份
   *
   * @return
   */
  @Override
  public List<PenaltyVo> getCurrentPenaltyInfo() {

    int j;
    List<PenaltyVo> penaltyInfoList = new ArrayList<>();
    List<JSONObject> administrativePenaltyList = new ArrayList<>();

    /* 获取环境基础信息 */
    List<JSONObject> environmentBaseInfoList = enterpriseService.getEnterpriseInfo(CacheConstant.ENTERPRISE_ENVIRONMENT).toJavaList(JSONObject.class);

    /* 获取行政处罚记录 */
    for (JSONObject jsonObject : environmentBaseInfoList) {
      JSONArray administrativePenaltyArray = Optional.ofNullable(jsonObject.getJSONObject(SystemConstant.ENVIRONMENTAL))
          .map(m -> m.getJSONObject(SystemConstant.ENVIRONMENT_BASE_INFO))
          .map(m -> m.getJSONArray("administrativePenaltyList"))
          .orElse(new JSONArray());

      administrativePenaltyList.addAll(administrativePenaltyArray.toJavaList(JSONObject.class));
    }

    /* 获取往前一年的行政处罚类型及处罚时间[yyyy-mm] */
    for (j = 0; j < administrativePenaltyList.size(); j++) {

      String penaltyDate = administrativePenaltyList.get(j).getString("date");
      if (Strings.isNullOrEmpty(penaltyDate)) {
        continue;
      }
      /* 年份为当年或者去年 */
      if (penaltyDate.substring(0, 4).equals(TimeTransferUtils.getSystemCurrentYear())
          ||
          penaltyDate.substring(0, 4).equals(
              (Integer.parseInt(TimeTransferUtils.getSystemCurrentYear()) - 1) + "")
          ) {
        /* 获取行政处罚类型 */
        String penaltyType = administrativePenaltyList.get(j).getString("administrativePenaltyType");
        if (!Strings.isNullOrEmpty(penaltyType)) {

          PenaltyVo penaltyVoMap = new PenaltyVo();
          penaltyVoMap.setDate(penaltyDate.substring(0, 7));
          penaltyVoMap.setAdministrativePenaltyType(penaltyType);

          penaltyInfoList.add(penaltyVoMap);
        }
      }
    }

    return penaltyInfoList;
  }


  /**
   * 环境信访情况统计-过滤投诉事件在当年的，
   * 按“投诉方式”字段对记录数做分组计数
   *
   * @return
   */
  @Override
  public Map<String, Object> getEnvironmentLetterStatus() {

    if (!redisTemplate.hasKey(CacheConstant.ENVIRONMENT_LETTER)) {

      /* 获取当月往前一年的时间列表 */
      List<String> dayList = TimeTransferUtils.getDayList();

      List<ComplaintWayVo> complaintWayInfoList = this.getCurrentComplaintWayInfo();

      /* 按投诉方式和时间分组统计 */
      Map<String, Map<String, Long>> result = complaintWayInfoList
          .stream()
          .collect(Collectors.groupingBy(ComplaintWayVo::getComplaintMethod,
              Collectors.groupingBy(ComplaintWayVo::getComplaintDate,
                  Collectors.counting())));

      /* 定义结果集列表 */
      List<Map<String, Object>> resultList = new ArrayList<>();

      /* 遍历分组统计结果集 */
      result.forEach((complaintMethod, dateAndCountMap) -> {
        Map<String, Object> methodAndCountMap = new HashMap<>();
        methodAndCountMap.put(SystemConstant.NAME, complaintMethod);
        List<Long> perMonthCountList = new ArrayList<>();

        /* 将dateAndCountMap的key遍历取出转为集合 */
        List<String> keys = dateAndCountMap.entrySet().stream().map(m -> m.getKey()).collect(Collectors.toList());

        /* 遍历当前月往前一年时间，设置每个月份每种投诉方式对应的记录数 */
        dayList.forEach(m -> {
          if (keys.contains(m)) {
            perMonthCountList.add(dateAndCountMap.get(m));
          } else {
            perMonthCountList.add(0L);
          }
        });
        methodAndCountMap.put(SystemConstant.VALUE, perMonthCountList);
        resultList.add(methodAndCountMap);
      });

      Map<String, Object> resultMap = new HashMap<>();
      resultMap.put("dateList", dayList);
      resultMap.put(SystemConstant.VALUE, resultList);

      /* 设置环境信访情况统计缓存过期时间 */
      redisTemplate.opsForValue().set(CacheConstant.ENVIRONMENT_LETTER,
          JSON.toJSONString(resultMap),
          appConfig.getChartDataCacheTime(),
          TimeUnit.SECONDS);

      return resultMap;

    } else {
      Object envLetter = redisTemplate.opsForValue().get(CacheConstant.ENVIRONMENT_LETTER);
      /* json 转 map */
      return JSON.parseObject(envLetter.toString(), Map.class);
    }
  }


  /**
   * 环境信访情况统计-获取往前一年的所有投诉方式及投诉时间[yyyy-mm]
   *
   * @return
   */
  @Override
  public List<ComplaintWayVo> getCurrentComplaintWayInfo() {

    int j;
    List<ComplaintWayVo> complaintWayList = new ArrayList<>();
    List<JSONObject> environmentalLetterList = new ArrayList<>();

    /* 获取环境基础信息 */
    List<JSONObject> environmentBaseInfoList = enterpriseService.getEnterpriseInfo(CacheConstant.ENTERPRISE_ENVIRONMENT).toJavaList(JSONObject.class);

    for (JSONObject jsonObject : environmentBaseInfoList) {
      JSONArray environmentalLetterArray = Optional.ofNullable(jsonObject.getJSONObject(SystemConstant.ENVIRONMENTAL))
          .map(m -> m.getJSONObject(SystemConstant.ENVIRONMENT_BASE_INFO))
          .map(m -> m.getJSONArray(SystemConstant.ENVIRONMENTAL_LETTER_LIST))  /* 获取环境信访记录 */
          .orElse(new JSONArray());

      environmentalLetterList.addAll(environmentalLetterArray.toJavaList(JSONObject.class));
    }

    /* 获取往前一年的投诉方式及投诉时间[yyyy-mm] */
    for (j = 0; j < environmentalLetterList.size(); j++) {

      String complaintDate = environmentalLetterList.get(j).getString("complaintDate");

      /* 年份为当年或者去年 */
      if (complaintDate.substring(0, 4).equals(TimeTransferUtils.getSystemCurrentYear())
          ||
          complaintDate.substring(0, 4).equals(
              (Integer.parseInt(TimeTransferUtils.getSystemCurrentYear()) - 1) + "")
          ) {
        /* 获取投诉方式 */
        String complaintMethod = environmentalLetterList.get(j).getString("complaintMethod");
        if (!Strings.isNullOrEmpty(complaintMethod)) {

          ComplaintWayVo dateMethodMap = new ComplaintWayVo();
          dateMethodMap.setComplaintDate(complaintDate.substring(0, 7));
          dateMethodMap.setComplaintMethod(complaintMethod);

          complaintWayList.add(dateMethodMap);
        }
      }
    }

    return complaintWayList;
  }


  /**
   * 获取 事故处理情况
   *
   * @return
   */
  @Override
  public int getAccidentHandleStatus() {

    if (!redisTemplate.hasKey(CacheConstant.ENVIRONMENTAL_PROTECTION_ACCIDENT_HANDLING)) {

      long count = 0;

      List<JSONObject> administrativePenaltyList = new ArrayList<>();

      /* 获取环境基础信息 */
      List<JSONObject> environmentBaseInfoList = enterpriseService.getEnterpriseInfo(CacheConstant.ENTERPRISE_ENVIRONMENT).toJavaList(JSONObject.class);

      for (JSONObject jsonObject : environmentBaseInfoList) {
        administrativePenaltyList = Optional.ofNullable(jsonObject.getJSONObject(SystemConstant.ENVIRONMENTAL))
            .map(m -> m.getJSONObject(SystemConstant.ENVIRONMENT_BASE_INFO))
            .map(m -> m.getJSONArray("administrativePenaltyList"))
            .orElse(new JSONArray()).toJavaList(JSONObject.class);
      }


      count = administrativePenaltyList.stream()
          .filter(administrativePenalty ->
              !StringUtils.isEmpty(administrativePenalty.getString("date"))
                  && administrativePenalty.getString("date").substring(0, 4).equals(TimeTransferUtils.getSystemCurrentYear())
          )
          .count();


      /* 添加环保事故处理情况redis缓存并设置缓存过期时间 */
      redisTemplate.opsForValue().set(CacheConstant.ENVIRONMENTAL_PROTECTION_ACCIDENT_HANDLING,
          count,
          appConfig.getChartDataCacheTime(),
          TimeUnit.SECONDS);

      return Integer.parseInt(count + "");
    } else {
      Object count = redisTemplate.opsForValue().get(CacheConstant.ENVIRONMENTAL_PROTECTION_ACCIDENT_HANDLING);
      return Integer.parseInt(count.toString());
    }
  }


  /**
   * 获取环保制度管理情况
   *
   * @return
   */
  @Override
  public int getEnvProtectRulesManageStatus() {

    if (!redisTemplate.hasKey(CacheConstant.ENVIRONMENTAL_PROTECTION_RULE_MANAGEMENT_STATUS)) {

      int count = 0;
      String envMonitorRecordString = "";

      /* 获取环境基础信息 */
      List<JSONObject> environmentBaseInfoList = enterpriseService.getEnterpriseInfo(CacheConstant.ENTERPRISE_ENVIRONMENT).toJavaList(JSONObject.class);

      for (JSONObject jsonObject : environmentBaseInfoList) {
        envMonitorRecordString = Optional.ofNullable(jsonObject.getJSONObject("environmental"))
            .map(m -> m.getJSONObject("environmentBaseInfo"))
            .map(m -> m.getJSONObject("pollutionPreventionManagementSituation"))
            .map(m -> m.getString("environmentalMonitoringRecord"))
            .orElse("");

        if (!Strings.isNullOrEmpty(envMonitorRecordString)) {
          count += 1;
        }
      }

      /* 添加环保制度管理情况redis缓存并设置缓存过期时间 */
      redisTemplate.opsForValue().set(CacheConstant.ENVIRONMENTAL_PROTECTION_RULE_MANAGEMENT_STATUS,
          count,
          appConfig.getChartDataCacheTime(),
          TimeUnit.SECONDS);

      return count;
    } else {
      Object count = redisTemplate.opsForValue().get(CacheConstant.ENVIRONMENTAL_PROTECTION_RULE_MANAGEMENT_STATUS);
      return Integer.parseInt(count.toString());
    }
  }


  /***
   * 环境污染物总量控制情况
   * @return
   */
  @Override
  public List getPollutionControl() {

    if (!redisTemplate.hasKey(CacheConstant.TOTAL_ENVIRONMENTAL_POLLUTANT_CONTROL)) {

      JSONObject tmpMap;
      JSONArray environmentBaseInfoList = enterpriseService.getEnterpriseInfo(CacheConstant.ENTERPRISE_ENVIRONMENT);
      List<EnvironmentBaseVo> environmentBaseVos = new ArrayList<>();

      for (int i = 0; i < environmentBaseInfoList.size(); i++) {
        tmpMap = Optional.ofNullable(environmentBaseInfoList.getJSONObject(i))
            .map(m -> m.getJSONObject("environmental"))
            .map(m -> m.getJSONObject("environmentBaseInfo"))
            .map(m -> m.getJSONObject("environmentalProtectionBasicInfo")).orElse(new JSONObject());
        if (!Strings.isNullOrEmpty(tmpMap.getString("primaryContaminant"))) {
          EnvironmentBaseVo baseVo = new EnvironmentBaseVo();
          baseVo.setPrimaryContaminant(tmpMap.getString("primaryContaminant"));
          baseVo.setTotalControl(tmpMap.getString("totalControl"));
          environmentBaseVos.add(baseVo);
        }
      }

      Map<String, List<EnvironmentBaseVo>> resultTmpMap = environmentBaseVos
          .stream()
          .collect(Collectors.groupingBy(EnvironmentBaseVo::getPrimaryContaminant));

      List<Map<String, Object>> resultList = this.getResultList(resultTmpMap);

      /* 设置环境污染物总量控制情况缓存过期时间 */
      redisTemplate.opsForValue().set(CacheConstant.TOTAL_ENVIRONMENTAL_POLLUTANT_CONTROL,
          JSON.toJSONString(resultList),
          appConfig.getChartDataCacheTime(),
          TimeUnit.SECONDS);

      return resultList;
    } else {
      Object pollutant = redisTemplate.opsForValue().get(CacheConstant.TOTAL_ENVIRONMENTAL_POLLUTANT_CONTROL);
      return JSON.parseArray(pollutant.toString(), Map.class);
    }
  }


  public List<Map<String, Object>> getResultList(Map<String, List<EnvironmentBaseVo>> resultTmpMap) {

    String regEx = "[^0-9]";
    Pattern p = Pattern.compile(regEx);

    List<Map<String, Object>> resultList = new ArrayList<>();

    resultTmpMap.forEach((k, v) -> {
      Map<String, Object> resultMap = new HashMap<>();
      resultMap.put(SystemConstant.NAME, k);
      Integer total = 0;
      for (EnvironmentBaseVo e : v) {
        if (e.getTotalControl() == null) {
          continue;
        }
        Matcher m = p.matcher(e.getTotalControl());
        total += Optional.ofNullable(m.replaceAll("").trim())
            .map(map -> Integer.parseInt("".equals(map) ? "0" : map)).orElse(0);
      }

      resultMap.put(SystemConstant.VALUE, total);
      resultList.add(resultMap);
    });

    return resultList;
  }


}
